The ScriptX exception system is made up of three parts:
guard
construct in the ScriptX language allows you to catch exceptions and handle them within your script.
report
generic function allows you to report your own exceptions within your scripts.
The core classes define a standard set of exception classes that represent common errors, warnings, or other unwanted situations that may occur during the execution of a script. In addition, you can create your own classes and instances to represent kinds of exceptions and specific exceptions that your code might report during its execution.
For more details on the core set of exception classes, see the ScriptX Class Reference. For more information on defining your own exceptions, see "Creating Exception Subclasses and Instances" on page 181.
guard
construct, which allows you to catch and handle exceptions within your scripts:guardThe guardedCode is an expression (often a compound expression) containing the code to be guarded. Code that may report an exception must be guarded if that exception is to be caught. Any ScriptX expression can be guarded, with the following exceptions:
guardedCode
[ catching
exceptionName[ lexicalName ]:[ action ]
... ]
[ on exit
exitCode ]
end
global
, unglobal
, or local
expression cannot be guarded. (A local
expression can be used inside a compound expression that is guarded. The global
and unglobal
expressions are permitted only at the top level.)
in module
expression cannot be guarded. (These expressions are discussed in Chapter 9, "Modules.")
catching
section contains a tagged list of exceptions to check for, each one matched with an expression to execute if an exception occurs. This list is sometimes referred to as the catch list. Use exceptionName to specify one of three types of values: an instance of an exception class (to catch a specific exception), an exception class (to catch any exception within a class of exceptions), or the keyword all
(to catch all exceptions).
Each item in the catch list can have a lexical name associated with its action. The optional lexicalName, if one is given, is bound to the argument that is reported with the exception, allowing the expression that catches and handles the exception to process this argument as well. When ScriptX reports an exception, the exception is bound to the global variable throwTag
, and its reporting argument, if defined, to the global variable throwArg
. These two global variables are covered in greater detail in the section "Retrieving Information about the Exception" on page 180. Think of each item in the tagged list of exceptions as being equivalent to throwTag throwArg
, where throwArg
is optional.
The optional on exit
section contains an expression (often a compound expression) that is always executed whether or not the guarded code reports an exception. The expression in on exit
is guaranteed to be executed.
Further details on each of these guard
clauses are given in the remainder of this section.
caught
and the throw again
expressions, which, when used within the catching
clause of the guard
construct, prevent the remaining statements in the catch list from being executed after an exception has been caught.
The caught
expression specifies that the exception has been caught. Once the exception has been caught, ScriptX immediately breaks out of the catching loop and does not check the remaining clauses in the catching
clause or any other catch lists. The caught
expression requires one argument, an expression containing the return value of the guard
clause if that guard
clause resulted in an exception. For example, if the guarded code is the generic function addMany
, and the script attempts to add too many items to a collection, the argument to caught
, and therefore the return value of guard
, might be an error message:
global myArray := new Array initialSize:10 growable:false
global otherArray := #(1,2,3,4,5,6,7,8,9,10,11,12)
-- now try to add too many items to an array
guard
addMany myArray otherArray
catching
boundedError: caught (print "Tried to add too many items" debug)
end
"Tried to add too many items"
An examination of myArray
shows that we succeeded in adding the first ten items before the exception was reported.
myArray
#(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Like caught
, the throw again
expression causes ScriptX to stop checking the remaining statements in this catching
clause. Unlike caught
, the exception is then reported again, which causes ScriptX to test each of the exceptions in any surrounding guard
constructs, or to drop the exception if there are no surrounding guard constructs. For example, if x
is some number, and y
is 0, the catching
construct prints a message and then reports the divideByZero
exception again, so any surrounding guard
constructs can catch it if needed.
guard (z := x/y)
catching
divideByZero: (print "Divide By Zero"; throw again)
end
To throw again
is to leave the exception uncaught. It is up to surrounding guard
expressions to catch the exception. If there is no surrounding guard
expression, or if the surrounding guard
expression fails to catch the exception, the thread dies, and no value is returned.
This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.